"There is no way to create a new policy from code.", yes you can.

Today I was reading chapter 12 Enterprise Document Management in Professional SharePoint 2013 Development, and it was stated that a new ProjectPolicy object could not be created from code, it could only be created using the user interface. So I took this as a challenge. During this I discovered that a ProjectPolicy is actually a hidden content type with some added xml in XmlDocuments. So this would mean that you could create the policy once, and probably distribute it using the content type hub. This was not mentioned, but searching on the web I found a blog post on this here. Looking at it, I remembered a demo at the DIWUG I saw some months ago, where this was explained and demonstrated.

Well though you probably wouldn't need to create a new policy from code, and using the content type hub is the way to go! I still was eager to challenge that you can't create a policy from code. Officially I agree with the notion that "There is no way to create a new policy from code.", as this can't be achieved using public api calls, as I found out looking at the ProjectPolicyConfig class. Unfortunately the needed methods and properties are mostly declareated as internal. Well, if you are familiar with reflection, than you know that this doesn't have to be a problem. Trying things out, I created a generic Reflection class, that I could use, called Reflection<T>:

public class Reflection<T>
{
    protected T _instance;

    public Reflection(T instance)
    {
        _instance = instance;
    }

    public static X CallStatic<X>(string method, params object[] par)
    {
        BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
        MethodInfo minfo = typeof(T).GetMethod(method, bindingFlags);
        return (X)minfo.Invoke(null, par);
    }

    public static void CallStatic(string method, params object[] par)
    {
        BindingFlags bindingFlags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public;
        MethodInfo minfo = typeof(T).GetMethod(method, bindingFlags);
        minfo.Invoke(null, par);
    }

    public void CallMethod(string method, params object[] arguments)
    {
        BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
        MethodInfo minfo = typeof(T).GetMethod(method, bindingFlags);
        minfo.Invoke(_instance, arguments);
    }

    public V CallMethod<V>(string method, params object[] arguments)
    {
        BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
        MethodInfo minfo = typeof(T).GetMethod(method, bindingFlags);
        return (V)minfo.Invoke(_instance, arguments);
    }

    public void SetValue(string property, object value)
    {
        BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
        PropertyInfo pinfo = typeof(T).GetProperty(property, bindingFlags);
        pinfo.SetValue(_instance, value);
    }

    public U GetValue<U>(string property)
    {
        BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
        PropertyInfo pinfo = typeof(T).GetProperty(property, bindingFlags);
        return (U)pinfo.GetValue(_instance);
    }

    public void SetFieldValue(string property, object value)
    {
        BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
        FieldInfo finfo = typeof(T).GetField(property, bindingFlags);
        finfo.SetValue(_instance, value);
    }

    public W GetFieldValue<W>(string property)
    {
        BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public;
        FieldInfo finfo = typeof(T).GetField(property, bindingFlags);
        return (W)finfo.GetValue(_instance);
    }

}
    

This class can be used to help with reflection tasks. I added a lot of code I didn't need, but this could come in handy some other time. Ok now back to the task at hand, creating a ProjectPolicy from code. Looking at the CreateProjectPolicy method of the ProjectPolicy class and SaveProjectPolicy method of the ProjectPolicyConfig class using a reflection tool, I saw what was needed to create, populate and save a ProjectPolicy. Using this info I created a sample site feature with a feature receiver to add the Policy.

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    SPSite site = properties.Feature.Parent as SPSite;
    if (site == null)
        return;

    ProjectPolicy pp = Reflection<ProjectPolicy>.CallStatic<ProjectPolicy>("CreateProjectPolicy", site, "Sample");
    Reflection<ProjectPolicy> pol = new Reflection<ProjectPolicy>(pp);

    //Save Project Policy - CloseDelete specific calls
    pol.SetValue("CloseDeleteOption", 2); // CloseDelete
    pol.SetValue("WorkflowId", string.Empty);
    pol.SetValue("NumberOfTimePeriodOnWorkflow", 0);
    pol.SetValue("TimePeriodOnWorkflow", "months");
    pol.SetValue("AllowWorkflowRecur", false);
    pol.SetValue("NumberOfTimePeriodOnWorkflowRecur", 0);
    pol.SetValue("TimePeriodOnWorkflowRecur", "months");
    pol.SetValue("NumberOfTimePeriodOnClose", 5);
    pol.SetValue("TimePeriodOnClose", "years");
    pol.SetValue("FieldNameOnDelete", "ProjectCloseDate");
    pol.SetValue("NumberOfTimePeriodOnDelete", 6);
    pol.SetValue("TimePeriodOnDelete", "months");

    //Save Project Policy Helper calls
    pol.SetValue("AllowEmailNotification", true);
    pol.SetValue("NumberOfTimePeriodOnEmailNotification", 3);
    pol.SetValue("TimePeriodOnEmailNotification", "months");
    pol.SetValue("AllowEmailFollowUp", true);
    pol.SetValue("NumberOfTimePeriodOnEmailFollowUp", 14);
    pol.SetValue("TimePeriodOnEmailFollowUp", "days");
    pol.SetValue("AllowPostpone", true);
    pol.SetValue("NumberOfTimePeriodOnPostpone", 3);
    pol.SetValue("TimePeriodOnPostpone", "months");

    //Save Project Policy calls
    pol.SetValue("CloseToReadOnly", true);
    pol.CallMethod("Save");
    pol.SetValue("Name", "Sample");
    pol.SetValue("Description", "Just a test to see if you can create a ProjectPolicy from code.");
    pol.CallMethod("Update");
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
    SPSite site = properties.Feature.Parent as SPSite;
    if (site == null)
        return;

    try
    {
        SPContentType ct = site.RootWeb.ContentTypes["Sample"];
        site.RootWeb.ContentTypes.Delete(ct.Id);
    }
    catch (Exception ex)
    {
        //Log exception
    }
}
    

After the feature was activated, the newly in code created ProjectPolicy was added, and on deactivation it is deleted by simply deleting the content type. As I already mentioned, using the content type hub is the way to go! In the screenshot below (Dutch language site), you can see the created ProjectPolicy or Site Policy.

Created policy

If you are interested in this solution, you can download it here.

Revision of text from 5/29/2013 Revision, added usage of params to simplify method calls